import doc
import kid
import types

def Template(source = None, file = None, fragment=1, format='default'):
    """The decorator make the function return dict get and replace by Kid template."""
    def TemplateDecorator(Func):
        def NewFunc(*args, **kwargs):
            Result = Func(*args, **kwargs)
            if type(Result) is types.DictType:
                Template = kid.Template(source=source, file=file, **Result)
            else:
                return str(Result)
            return Template.serialize(fragment=fragment, output='xml', format=format)
            
        return NewFunc
    return TemplateDecorator

DocTemplate = """<?xml version="1.0" ?>
<doc xmlns:py="http://purl.org/kid/ns#">
    <header>
        <version>${Doc.Version}</version>
        <lastId>${Doc.LastID}</lastId>
    </header>
    <content>
        ${XML(NodeToXML(Doc.Root))}
    </content>
</doc>
"""

NodeTemplate = """<?xml version="1.0" ?>
<node xmlns:py="http://purl.org/kid/ns#" class="${Node.__class__}" id="${Node.ID}">
    ${XML(DataToXML(Node.Data))}
    <span py:if="hasattr(Node, 'Children')" py:replace="XML(ChildrenToXML(Node.Children))">
    </span>
</node>
"""

DataTemplate = """<?xml version="1.0" ?>
<data xmlns:py="http://purl.org/kid/ns#">
    <element py:for="name in Data" name="${name}" py:content="Data[name]">
    </element>
</data>
"""

ChildrenTemplate = """<?xml version="1.0" ?>
<children xmlns:py="http://purl.org/kid/ns#">
    <span py:for="Child in Children" py:replace="XML(NodeToXML(Child))">
    </span>
</children>
"""

@Template(source=ChildrenTemplate)
def ChildrenToXML(Children):
    return dict(Children=Children, NodeToXML=NodeToXML)

@Template(source=DataTemplate)
def DataToXML(Data):
    return dict(Data=Data, DataToXML=DataToXML)

@Template(source=NodeTemplate)
def NodeToXML(Node):
    return dict(Node=Node, NodeToXML=NodeToXML, DataToXML=DataToXML, ChildrenToXML=ChildrenToXML)

@Template(source=DocTemplate, format='pretty', fragment=0)
def DocToXML(Doc):
    return dict(Doc=Doc, NodeToXML=NodeToXML)

xmla = """<?xml version="1.0" encoding="utf-8"?>
<doc>
<header version="1.0">
    <title>test</title>
    <createDate>2007-11-10 15:41:23.097000</createDate>
    <updateDate>2007-11-10 15:41:23.097000</updateDate>
    <edition>0</edition>
    <lastId>7</lastId>

</header>
<content>
    <node class="widget_base.BlockBase" id="0">
        <data>
            <element name="version">1.0</element>
        </data>
        <children>
            <node class="standard.TitleBar" id="6">
                <data>

                    <element name="version">1.0</element>
                    <element name="title">Title</element>
                </data>
            </node>
            <node class="widget_base.BlockBase" id="1">
                <data>
                    <element name="version">1.0</element>

                </data>
                <children>
                    <node class="widget_base.BlockBase" id="4">
                        <data>
                            <element name="version">1.0</element>
                        </data>
                        <children />
                    </node>

                    <node class="widget_base.BlockBase" id="5">
                        <data>
                            <element name="version">1.0</element>
                        </data>
                        <children />
                    </node>
                </children>
            </node>

            <node class="widget_base.BlockBase" id="2">
                <data>
                    <element name="version">1.0</element>
                </data>
                <children />
            </node>
            <node class="widget_base.BlockBase" id="3">
                <data>

                    <element name="version">1.0</element>
                </data>
                <children />
            </node>
        </children>
    </node>
</content>
</doc>"""

def LoadNode(Doc, Node, Parent):
    Moudle, TypeName = Node.getAttribute('class').split('.')
    ID = int(Node.getAttribute('id'))
    if Parent:
        print 'parent : ' + str(Parent.ID) +' id ' + Node.getAttribute('id')
    
    TypeClass = getattr(globals()[Moudle], TypeName)
    NewNode = TypeClass()
    NewNode.Parent = Parent
    NewNode.ID = ID
    Doc.NodeMap[ID] = NewNode

    Data = Node.getElementsByTagName('data')
    if Data:
        Elements = Data[0].getElementsByTagName('element')
        for i in range(Elements.length):
            if Elements[i] in Data[0].childNodes:
                DataName = Elements[i].getAttribute('name')
                DataValue = Elements[i].childNodes[0].data
                NewNode.Data[DataName] = DataValue
        
    Children = Node.getElementsByTagName('children')
    if Children:
        Nodes = Children[0].getElementsByTagName('node')
        for i in range(Nodes.length):
            if Nodes[i] in Children[0].childNodes:
                NewNode.Children.append(LoadNode(Doc, Nodes[i], NewNode))
        
    return NewNode

def XMLToDoc(XML):
    import xml.dom.minidom
    import datetime
    
    Doc = xml.dom.minidom.parseString(XML)
    
    NewDoc = doc.Doc()      
    
    NewDoc.Title = Doc.getElementsByTagName('title')[0].childNodes[0].data
    NewDoc.CreateDate = Doc.getElementsByTagName('createDate')[0].childNodes[0].data
    NewDoc.UpdateDate = Doc.getElementsByTagName('updateDate')[0].childNodes[0].data
    NewDoc.Edition = Doc.getElementsByTagName('edition')[0].childNodes[0].data
    NewDoc.LastID = Doc.getElementsByTagName('lastId')[0].childNodes[0].data
    
    doc.Doc.LoadModules(globals())
    
    NewDoc.Root = LoadNode(NewDoc, Doc.getElementsByTagName('node')[0], None)
    
    return NewDoc